﻿using ARchGL.Declaration.Platform.Domain.Entities;
using ARchGL.Declaration.Platform.Service.Dtos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using TDF.Core.Exceptions;
using TDF.Core.Ioc;
using TDF.Data.Repository;

namespace ARchGL.Declaration.Platform.Service
{
    /// <summary>
    /// 报表服务
    /// </summary>
    public partial class ProjectService
    {
        #region 报表提供

        ///待审核申请信息-统计
        public WaitReviewReportDto WaitReviewReport(Guid areaId)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var account = repository.FindEntity<Account>(areaId);
                if (account.IsNull()) throw new KnownException("用户不存在");

                //项目申请，工程验收
                var projectReviewQuery = repository.IQueryable<DP_Project_Review_History>().WhereByStatus(AuditStatus.待审核);
                //变更申请
                var projectChangeQuery = repository.IQueryable<DP_Project_Change_History>().WhereByStatus(AuditStatus.待审核);
                //BIM申请，元素报表
                var submitReviewQuery = repository.IQueryable<SubitemReview>().WhereByStatus(AuditStatus.待审核);

                if (account.Type != AccountType.管理员)
                {
                    projectReviewQuery = projectReviewQuery.Where(x => x.AuditId == areaId || x.CreatorId == areaId || x.ModifierId == areaId || x.BuilderUnitIds.Contains(areaId.ToString()));

                    projectChangeQuery = projectChangeQuery.Where(x => x.AuditId == areaId || x.CreatorId == areaId || x.BuilderUnitIds.Contains(areaId.ToString()));

                    submitReviewQuery = submitReviewQuery.Where(x => x.AuditId == areaId || x.CreatorId == areaId || x.BuilderUnitIds.Contains(areaId.ToString()));
                }

                return new WaitReviewReportDto
                {
                    TotalCount1 = projectReviewQuery.Count(x => x.Type != ReviewType.分部工程),
                    TotalCount2 = projectChangeQuery.Count(x => x.Status == AuditStatus.待审核),
                    TotalCount3 = projectReviewQuery.Count(x => x.Type == ReviewType.分部工程),
                    TotalCount4 = submitReviewQuery.Count(x => x.Type == ApplyForType.BIM认定),
                    TotalCount5 = submitReviewQuery.Count(x => x.Type == ApplyForType.元素表报),
                };
            }
        }

        ///月报统计
        public List<MonthReportDto> MonthReport(DateTime date, Guid areaId)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var account = repository.FindEntity<Account>(areaId);
                if (account.IsNull()) throw new KnownException("用户不存在");

                if (account.Type != AccountType.区县帐号 && account.Type != AccountType.管理员)
                    throw new KnownException("当前用户没有权限访问");

                var dict = new Dictionary<string, MonthReportDto>();
                var accountQuery = repository.IQueryable<Account>().WhereByStatus(1);
                var projectQuery = repository.IQueryable<DP_Project>().WhereByCreatedTime(date).WhereBySoftDeletedStatus(SoftDeletedStatus.正常);
                var subitemItemQuery = repository.IQueryable<SubitemReview>().WhereByCreatedTime(date).WhereByStatus(AuditStatus.已完成);
                if (account.Type == AccountType.区县帐号)
                {
                    accountQuery = accountQuery.WhereByAccountIds(account.Id.ToString());
                }
                else
                {
                    accountQuery = accountQuery.WhereByType(AccountType.区县帐号);
                }

                var projectResult = projectQuery.ToList();
                var subitemResult = subitemItemQuery.ToList();

                foreach (var item in accountQuery.ToList())
                {
                    var projectResult1 = projectResult.Where(x => x.Code.IndexOf(item.Number) == 0 && x.ParentId == Guid.Empty);//项目
                    var projectResult2 = projectResult.Where(x => x.Code.IndexOf(item.Number) == 0 && x.ParentId != Guid.Empty);//工程

                    var dto = new MonthReportDto
                    {
                        Month = date.Month,
                        Name = item.Name,
                        Number = item.Number,
                    };

                    dto.TotalArray = new int[10];

                    var hasValue = CheckHasValue(projectResult1);

                    if (hasValue)
                    {
                        dto.TotalArray[0] = projectResult1.Count();
                        dto.TotalArray[1] = projectResult1.Count(x => x.Status == AuditStatus.未报审);
                        dto.TotalArray[2] = projectResult1.Count(x => x.Status != AuditStatus.已完成 && x.Status != AuditStatus.未报审);
                        dto.TotalArray[3] = projectResult1.Count(x => x.Status == AuditStatus.已完成);
                    }

                    hasValue = CheckHasValue(projectResult2);
                    if (hasValue)
                    {
                        dto.TotalArray[4] = projectResult2.Count();
                        dto.TotalArray[5] = projectResult2.Count(x => x.Status == AuditStatus.未报审);
                        dto.TotalArray[6] = projectResult2.Count(x => x.Status != AuditStatus.已完成 && x.Status != AuditStatus.未报审);
                        dto.TotalArray[7] = projectResult2.Count(x => x.Status == AuditStatus.已完成);
                    }

                    hasValue = CheckHasValue(subitemResult);
                    if (hasValue)
                    {
                        dto.TotalArray[8] = subitemResult.Count(x => x.AuditId == item.Id && x.Type == ApplyForType.BIM认定);
                        dto.TotalArray[9] = subitemResult.Count(x => x.AuditId == item.Id && x.Type == ApplyForType.元素表报);
                    }
                    dict.Add(item.Number, dto);
                }

                return dict.Values.ToList();
            }
        }

        private bool CheckHasValue<T>(IEnumerable<T> query)
        {
            try
            {
                query.Count();
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }

        private int asdfasdf(IEnumerable<DP_Project> query, Expression<Func<DP_Project, bool>> fn)
        {
            if (query == null) return 0;
            return 0;
        }

        ///已报未报工程-统计
        public ProjectDeclarationReportDto ProjectDeclarationReport(Guid areaId)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase<DP_Project>>())
            {
                var query = repository.IQueryable().WhereByIsChildParject(true).WhereByAreaId(areaId);

                var submit = query.Count(x => x.Status != AuditStatus.未报审);//已报
                var unsubmit = query.Count(x => x.Status == AuditStatus.未报审);//未报

                return new ProjectDeclarationReportDto
                {
                    Submit = submit,
                    Unsubmit = unsubmit,
                };
            }
        }

        ///已报工程中审核通过与未通过-统计
        public ProjectCategoryFirstCategoryReportDto ProjectFileReport(Guid areaId)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var projectList = repository.IQueryable<DP_Project>()//获取项目信息
                    .WhereByAreaId(areaId)
                    .WhereByIsChildParject(true)
                    .WhereByStatusNotEquals(AuditStatus.未报审)//不等于未上传即 已上报项目
                    .ToDto()
                    .OrderByDescending(x => x.Status)
                    .ToPageResult1(1, 10000);

                var projectCategoryList = GetAllProjectCategoryPagedList().Rows//获取分类信息
                    .Where(x => x.ParentId == Guid.Empty)
                    .OrderBy(x => x.Sort).ToList();

                var overviewList = AssembleOverview(projectList, projectCategoryList, repository);//数据组装

                var entity = new ProjectCategoryFirstCategoryReportDto();

                foreach (var item in overviewList.Rows)
                {
                    if (item.FirstCategoryStatus1 == AuditStatus.未报审) entity.FirstCategoryUnsubmitCount1 += 1;
                    else if (item.FirstCategoryStatus1 == AuditStatus.待审核) entity.FirstCategoryReviewCount1 += 1;
                    else if (item.FirstCategoryStatus1 == AuditStatus.被打回) entity.FirstCategoryRejectCount1 += 1;
                    else if (item.FirstCategoryStatus1 == AuditStatus.已完成) entity.FirstCategoryPassCount1 += 1;

                    if (item.FirstCategoryStatus2 == AuditStatus.未报审) entity.FirstCategoryUnsubmitCount2 += 1;
                    else if (item.FirstCategoryStatus2 == AuditStatus.待审核) entity.FirstCategoryReviewCount2 += 1;
                    else if (item.FirstCategoryStatus2 == AuditStatus.被打回) entity.FirstCategoryRejectCount2 += 1;
                    else if (item.FirstCategoryStatus2 == AuditStatus.已完成) entity.FirstCategoryPassCount2 += 1;

                    if (item.FirstCategoryStatus3 == AuditStatus.未报审) entity.FirstCategoryUnsubmitCount3 += 1;
                    else if (item.FirstCategoryStatus3 == AuditStatus.待审核) entity.FirstCategoryReviewCount3 += 1;
                    else if (item.FirstCategoryStatus3 == AuditStatus.被打回) entity.FirstCategoryRejectCount3 += 1;
                    else if (item.FirstCategoryStatus3 == AuditStatus.已完成) entity.FirstCategoryPassCount3 += 1;

                    if (item.FirstCategoryStatus4 == AuditStatus.未报审) entity.FirstCategoryUnsubmitCount4 += 1;
                    else if (item.FirstCategoryStatus4 == AuditStatus.待审核) entity.FirstCategoryReviewCount4 += 1;
                    else if (item.FirstCategoryStatus4 == AuditStatus.被打回) entity.FirstCategoryRejectCount4 += 1;
                    else if (item.FirstCategoryStatus4 == AuditStatus.已完成) entity.FirstCategoryPassCount4 += 1;
                }

                return entity;
            }
        }

        ///已报工程中提交文件数-统计
        public List<ProjectSubmitReportDto> ProjectSubmitReport(Guid areaId)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var projectIdList = repository.IQueryable<DP_Project>()
                    .WhereByAreaId(areaId)
                    .WhereByIsChildParject(true)
                    .WhereByStatusNotEquals(AuditStatus.未报审)//不等于未上传即 已上报项目
                    .Select(x => x.Id).ToList();

                if (projectIdList.Count == 0) return null;//无提交记录直接返回

                var projectQuery = repository.IQueryable<DP_Project_File>().WhereByProjectIdList(projectIdList).OrderBy(x => x.CreatedTime);//项目文件
                var historyList = repository.IQueryable<DP_Project_Review_History>().WhereByProjectIdList(projectIdList).ToList();

                var list = new List<ProjectSubmitReportDto>();
                var dict = new Dictionary<string, ProjectSubmitReportDto>();

                foreach (var item in projectQuery)
                {
                    if (!historyList.Any(x => x.ProjectId == item.ProjectId && x.FirstCategoryId == item.FirstCategoryId)) continue;//未提交审核不记入统计

                    var date = item.CreatedTime.ToString("yyyy-MM-dd");
                    if (dict.ContainsKey(date))
                    {
                        dict[date].Count += 1;
                    }
                    else
                    {
                        dict.Add(date, new ProjectSubmitReportDto
                        {
                            Date = date,
                            Count = 1,
                        });
                    }
                }

                return dict.Values.ToList();
            }
        }

        ///已报工程中审核文件数-统计
        public ProjectReviewReport ProjectReviewReport(Guid areaId)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var projectIdList = repository.IQueryable<DP_Project>().WhereByAreaId(areaId).WhereByIsChildParject(true)
                    .Select(x => x.Id).ToList();
                var result = new ProjectReviewReport();

                if (projectIdList.Count > 0)
                {
                    var query = repository.IQueryable<DP_Project_Review_History>().WhereByProjectIdList(projectIdList).OrderByDescending(x => x.CreatedTime);
                    var dateList = new List<DateTime>();
                    foreach (var item in query)
                    {//每个分部工程下的状态只统计最后一次
                        if (dateList.Contains(item.SubmitTime)) continue;

                        switch (item.Status)
                        {
                            case AuditStatus.待审核:
                                result.ReviewingCount += 1;
                                break;
                            case AuditStatus.被打回:
                                result.RejectCount += 1;
                                break;
                            case AuditStatus.已完成:
                                result.PassCount += 1;
                                break;
                            default:
                                break;
                        }
                        dateList.Add(item.SubmitTime);
                    }
                }

                return result;
            }
        }

        ///单项申请状态-统计
        public ProjectSubitemReportDto ProjectSubitemReport(Guid areaId, ApplyForType type)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase<SubitemReview>>())
            {
                var query = repository.IQueryable().WhereByAuditId(areaId).WhereByType(type);
                return new ProjectSubitemReportDto
                {
                    Status2 = query.Count(x => x.Status == AuditStatus.已完成),
                    Status4 = query.Count(x => x.Status != AuditStatus.已完成),
                };
            }
        }

        #endregion
    }
}
